package com.wardrobe.soa.api.user;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.google.common.collect.Maps;
import com.wardrobe.dao.userinfo.UserInfoDao;
import com.wardrobe.domain.user.UserFromBean;
import com.wardrobe.domain.user.UserInfo;
import com.wardrobe.domain.userinfo.UserInfoBean;
import com.wardrobe.soa.common.ApiResult;
import com.wardrobe.soa.common.SmsmsgConsant;
import com.wardrobe.soa.common.SmsmsgSendBean;
import com.wardrobe.soa.huanxin.HuanXinUtil;
import com.wardrobe.soa.utils.CommonConsant;
import com.wardrobe.soa.utils.DateConsant;
import com.wardrobe.soa.utils.SmsmsgUtil;
import io.swagger.client.model.User;
import org.apache.shiro.crypto.hash.Sha512Hash;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;

/**
 * Created by m1304 on 2018/8/6.
 */
@Service("userService")
public class UserService {

    private static final Logger logger = LoggerFactory.getLogger(UserService.class);

    public static volatile Map<String,Map<String,Object>> msgMap = Maps.newConcurrentMap();

    @Resource
    private UserDao userDao;
    @Resource
    private UserInfoDao userInfoDao;
    public  synchronized ApiResult saveUser(UserFromBean fromBean){
        logger.warn("save user {},msgMap  {}",fromBean.toString(),msgMap.toString());
        if(fromBean.getPassword().length() < 6 || fromBean.getPassword().length() > 20){
            return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"超出密码长度","");
        }

        if(!fromBean.getPassword().equals(fromBean.getTwicePassword())){
            return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"密码不一致！请重新输入","");
        }
        if(userDao.queryUserForMobile(fromBean.getMobileNumber())){
            return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"手机号已存在！请重新输入","");
        }

        String key = formatMsgKey(fromBean.getMobileNumber(),0);
        Map<String, Object> msg = msgMap.get(key);
        if(msg == null || msg.size() == 0){
            return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"请发送验证码","");
        }else {
            long lastTime = (Long) msg.get("time");
            //超过十分钟
            if(System.currentTimeMillis() >= lastTime + DateConsant.TEN_MINUTE_MILLISECOND){
                return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"验证码已超过10分钟，请重新发送","");
            }else{
                if(!msg.get("code").equals(fromBean.getMsgCode())){
                    return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"验证码有误，请重新输入","");
                }else{
                    msgMap.remove(key);
                }
            }
        }

        UserInfo info = new UserInfo();
        info.setMobileNumber(fromBean.getMobileNumber());
        try {
            String encodedPassword = new Sha512Hash(fromBean.getPassword()).toBase64();
            info.setPassword(encodedPassword);
            int flag = userDao.insertUser(info);
            if(flag == 1){
                UserInfoBean infoBean= new UserInfoBean();
                infoBean.setUserId(info.getId());
                userInfoDao.insertUserInfo(infoBean);
                //注册环信账号
//                User user = new User();
//                user.setUsername(fromBean.getMobileNumber());
//                user.setPassword(fromBean.getPassword());
//                HuanXinUtil.registerHuanXin(user);
//                HuanXinUtil.addFriendSingle(fromBean.getMobileNumber());
                return new ApiResult(CommonConsant.successCode, CommonConsant.success,"注册成功","");
            }else{
                return new ApiResult(CommonConsant.serverFailedCode, CommonConsant.failed,CommonConsant.serverFailedMsg,"");
            }
        }catch (Exception e){
            logger.error("saveUser_err",e);
        }
        return new ApiResult(CommonConsant.serverFailedCode, CommonConsant.failed,CommonConsant.serverFailedMsg,"");
    }

    public  synchronized ApiResult reSet(UserFromBean fromBean){
        logger.warn("reset user {},msgMap  {}",fromBean.toString(),msgMap.toString());
        if(fromBean.getPassword().length() < 6 || fromBean.getPassword().length() > 20){
            return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"超出密码长度","");
        }
        String key = formatMsgKey(fromBean.getMobileNumber(),1);
        Map<String, Object> msg = msgMap.get(key);
        if(msg == null || msg.size() == 0){
            return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"请发送验证码","");
        }else {
            long lastTime = (Long) msg.get("time");
            //超过十分钟
            if(System.currentTimeMillis() >= lastTime + DateConsant.TEN_MINUTE_MILLISECOND){
                return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"验证码已超过10分钟，请重新发送","");
            }else{
                if(!msg.get("code").equals(fromBean.getMsgCode())){
                    return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"验证码有误，请重新输入","");
                }else{
                    msgMap.remove(key);
                }
            }
        }

        if(!fromBean.getPassword().equals(fromBean.getTwicePassword())){
            return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"密码不一致！请重新输入","");
        }
        UserInfo info = new UserInfo();
        info.setMobileNumber(fromBean.getMobileNumber());
        try {
            String encodedPassword = new Sha512Hash(fromBean.getPassword()).toBase64();
            info.setPassword(encodedPassword);
            int flag = userDao.modifyUserPassword(info);
            if(flag == 1){
                return new ApiResult(CommonConsant.successCode, CommonConsant.success,"重置密码成功","");
            }else{
                return new ApiResult(CommonConsant.serverFailedCode, CommonConsant.failed,CommonConsant.serverFailedMsg,"");
            }
        }catch (Exception e){
            logger.error("saveUser_err",e);
        }
        return new ApiResult(CommonConsant.serverFailedCode, CommonConsant.failed,CommonConsant.serverFailedMsg,"");
    }

    public ApiResult getLoginUser(String mobileNumber,String password){
        logger.warn("login param {},{}",mobileNumber,password);
        try {
            String encodedPassword = new Sha512Hash(password).toBase64();
            Map<String, Object> userInfo = userDao.getUser(mobileNumber, encodedPassword);
            if(userInfo.size() > 0){
                return new ApiResult(CommonConsant.successCode, CommonConsant.success,"登录成功",userInfo);
            }else{
                return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"登录失败","");
            }
        }catch (Exception e){
            logger.error("getUser_err",e);
        }
        return new ApiResult(CommonConsant.serverFailedCode, CommonConsant.failed,CommonConsant.serverFailedMsg,"");
    }

    /**
     * type == 0 注册
     * type == 1 重置密码
     * @param mobileNumber
     * @param type
     * @return
     */
    public ApiResult sendPhoneMsgCode(String mobileNumber,int type){
        String key = formatMsgKey(mobileNumber,type);
        //之前已经发送过短信
        if(msgMap.get(key) != null && msgMap.get(key).size() > 0){
            long lastTime = (Long) msgMap.get(key).get("time");
            //超过十分钟短信则失效
            if(System.currentTimeMillis() < lastTime + DateConsant.ONE_MINUTE_MILLISECOND){
                return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"1分钟只能发一次验证码","");
            }
        }
        try {
            Map<String,Object> data = Maps.newHashMap();
            int randomNum = createRandomNum();
            data.put("code",randomNum);
            SendSmsResponse sms = SmsmsgUtil.sendSms(mobileNumber, SmsmsgConsant.registerSignName, new SmsmsgSendBean(type == 0 ? SmsmsgConsant.registerCode : SmsmsgConsant.reSetPasswordCode, data));
            if(sms.getCode().equals("OK")){
                Map<String,Object> tMap = Maps.newHashMap();
                tMap.put("code",randomNum);
                tMap.put("time",System.currentTimeMillis());
                msgMap.put(key,tMap);
                logger.warn("msgMap-->{}",msgMap.toString());
                return new ApiResult(CommonConsant.successCode, CommonConsant.success,"发送验证码成功",sms);
            }else{
                return new ApiResult(CommonConsant.bussinessFailedCode, CommonConsant.failed,"发送验证码失败",sms);
            }
        } catch (ClientException e) {
            logger.error("sendSms_err",e);
        }
        return new ApiResult(CommonConsant.serverFailedCode, CommonConsant.failed,CommonConsant.serverFailedMsg,"");
    }

    int createRandomNum(){
        return (int) ((Math.random() * 9 + 1) * 100000);
    }

    String formatMsgKey(String mobileNumber, int type){
        return mobileNumber + "_" + type;
    }


}
